package com.qf.service.impl;

import com.github.pagehelper.PageInfo;

import com.github.pagehelper.util.StringUtil;
import com.qf.cache.CategoriesCache;
import com.qf.constans.ResultCode;
import com.qf.event.CategoryCacheChangeEvent;
import com.qf.exceptions.AddDataException;
import com.qf.mapper.CategoryMapper;
import com.qf.pojo.Categories;
import com.qf.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by jackiechan on 2021/6/8 10:57
 *
 * @author jackiechan
 */
@Service
@Transactional
public class CategoryServiceImpl implements CategoryService {
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private CategoriesCache categoriesCache;
    @Autowired
    private ApplicationContext context;
    @Autowired
    private CategoryCacheChangeEvent event;

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public PageInfo<Categories> findAllCategoriesByPage(int page, int limit,String categoryname, Long status) {
        PageInfo<Categories> pageInfo = null;
        List<Categories> categoriesList = categoriesCache.getAllData();//缓存中如果没有数据,我们不查询数据库,因为缓存中没有基本就代表了数据库中也没有
        List<Categories> realCategoriesList  = categoriesList.stream().filter(categories -> {
            boolean isFetchName = true;
            boolean isFetchStatus = true;
            String categoryname1 = categories.getCategoryname();
            Long status1 = categories.getStatus();
            if (!StringUtil.isEmpty(categoryname)) {
                isFetchName = categoryname1.contains(categoryname);
            }
            if (status != null && status != -100) {
                isFetchName = status1 == status;
            }
            return isFetchName && isFetchStatus;

        }).collect(Collectors.toList());


        int last_index=limit;//放置第一页就没有数据，所以默认最后一页是limit
        if(page*limit>=realCategoriesList.size()){
            last_index=realCategoriesList.size();//如果分页长度超出总长度，则分割页就是总页码

        }else{
            last_index=page*limit;
        }
        if ((page - 1) * limit >= realCategoriesList.size()) {
            //起点超出查询范围了,直接返回空数据
            pageInfo = new PageInfo<>();
            return pageInfo;
        }
        //切割集合,上面的代码都是怕越界而做的判断
        List<Categories> subList = realCategoriesList.subList((page - 1) * limit , last_index);
        pageInfo = new PageInfo<>(subList);
        pageInfo.setTotal(realCategoriesList.size());//设置总长度为符合条件的集合的长度
        return pageInfo;


    }


    @Override
    public void addCategory(Categories categories) {
        if (categories == null||categories.isNull()) {
            throw new AddDataException("数据不能为空", ResultCode.NULL_DATA);
        }
        categoryMapper.addCategoy(categories);
        //更新缓存,如果在这里直接操作缓存,万一出现异常,会导致事务回滚,添加失败,更新缓存应该要影响添加数据吗?
        //经过分析发现,即便是更新缓存失败,也不应该回滚数据,也就是说这是两个完全独立的操作
        //Event 事件,相当于拿着喇叭喊了一嗓子,等着听到的人去执行
        context.publishEvent(event);//发送事件,解耦
    }
}